package service

import (
	"IrisStandard/model"
	"IrisStandard/storage"
	"IrisStandard/util"
	"github.com/go-xorm/xorm"
	"log"
	"strconv"
)

type UserService interface {
	NextUserId(session *xorm.Session) 	(string, error)
	CheckExist(phone string)			(bool, error)
	Add(user model.User) 				(bool, error)
	GetByPhone(phone string) 			(*model.User, error)
}

type userService struct {}

func NewUserService() UserService {
	return &userService{}
}

const userIdStartBy = 1000001

func (u userService) NextUserId(session *xorm.Session) (string, error) {
	var maxIdStr string
	has, err := storage.Mysql.SQL("select max(user_id) from t_user").Get(&maxIdStr)
	if err != nil {
		return "", err
	}
	maxId, _ := strconv.Atoi(maxIdStr)
	if has && maxId != 0 {
		return strconv.Itoa(maxId + 1), nil
	} else {
		user := new(model.User)
		count, err := storage.Mysql.Count(user)
		if err != nil {
			return "", err
		}
		return strconv.Itoa(int(count + userIdStartBy)), nil
	}
}

func (u userService) CheckExist(phone string) (bool, error) {
	has, err := storage.Mysql.Exist(&model.User{Phone: phone})
	if err != nil {
		log.Println(err)
		return false, err
	}
	return has, nil
}

func (u userService) Add(user model.User) (bool, error) {
	session := storage.Mysql.NewSession()
	defer session.Close()
	err := session.Begin()
	// 再次检查是否已存在
	has, err := session.Exist(&model.User{Phone: user.Phone})
	if err != nil {
		log.Println(err)
		return false, err
	}
	if has {
		return false, nil
	}
	userId, err := u.NextUserId(session)
	if err != nil {
		log.Println(err)
		return false, err
	}
	user.UserId = userId
	password := util.StrToMd5(userId + util.StrToMd5(user.Password))
	user.Password = password
	_, err = session.Insert(user)
	if err != nil {
		log.Println(err)
		_ = session.Rollback()
		return false, err
	}
	err = session.Commit()
	if err != nil {
		log.Println(err)
		return false, err
	}
	return true, nil
}

func (u userService) GetByPhone(phone string) (*model.User, error) {
	user := model.User{}
	has, err := storage.Mysql.Where("phone = ?", phone).Get(&user)
	if err != nil {
		log.Println(err)
		return nil, err
	}
	if has {
		return &user, nil
	} else {
		return nil, nil
	}
}